1 module hip.util.betterc; 2 template getParams (alias fn) 3 { 4 static if ( is(typeof(fn) params == __parameters) ) 5 alias getParams = params; 6 } 7 8 9 T New(T, Args...)(Args args) 10 { 11 import core.stdc.stdlib:malloc; 12 import core.lifetime:emplace; 13 align(__traits(classInstanceAlignment, T)) 14 void[] baseMem = malloc(__traits(classInstanceSize, T))[0..__traits(classInstanceSize, T)]; 15 16 T ret = cast(T)baseMem.ptr; 17 emplace!T(ret, args); 18 return ret; 19 } 20 21 22 enum GenCPPInterface(Self, itf) = () 23 { 24 string ret = "class _" ~ __traits(identifier, itf)~"Impl : itf {" ~ q{ extern(C++): 25 Self self; 26 this(Self self){this.self = self;} 27 }; 28 29 import std.traits; 30 static foreach(fn; __traits(allMembers, itf)) 31 {{ 32 string mem = "__traits(getMember, itf, \""~ fn~ "\")"; 33 string retT = "ReturnType!("~mem~")"; 34 string params = "getParams!("~mem~")"; 35 36 ret~= "override " ~ retT ~ " " ~ fn ~ ("("~params~")") ~ "{"~ 37 "return (cast(Self)self)."~fn~"(__traits(parameters));}"; 38 }} 39 return ret ~ "}"; 40 }(); 41 42 extern(C++) class CppObject 43 { 44 this(){initialize();} 45 void initialize(){} 46 } 47 48 extern(C++) class CppInterface(Self, Interfaces...) : CppObject 49 { 50 static foreach(itf; Interfaces) 51 { 52 mixin(q{private itf }, ("_"~__traits(identifier, itf)) ~ ";"); 53 } 54 55 override void initialize() 56 { 57 import std.traits:ReturnType; 58 static foreach(itf; Interfaces) 59 { 60 mixin(GenCPPInterface!(Self, itf)); 61 mixin( ("_"~__traits(identifier, itf)) ~(" = New!(_" ~__traits(identifier, itf) ~ "Impl)(cast(Self)this);")); 62 } 63 } 64 65 66 T getInterface(T)() 67 { 68 static if(__traits(hasMember, Self, "_"~T.stringof)) 69 return mixin("_",T.stringof); 70 else static if(is(T == Self)) 71 return cast(Self)this; 72 else return null; 73 } 74 75 ~this() 76 { 77 import core.stdc.stdlib; 78 static foreach(itf; Interfaces) 79 {{ 80 alias mem = __traits(getMember, Self, "_"~itf.stringof); 81 destroy(mem); 82 free(cast(void*)mem); 83 }} 84 } 85 }